package main

import "fmt"

type Cat struct {
	Name  string
	Age   int
	Color string
}
type A struct {
	a map[string]int
}

func main() {
	//structDemo()
	//structCopy()
	initStruct()
}

func structDemo() {
	/*
		张老太养了两只猫：一只名字叫小白，今年3岁，白色
		还有一只叫小花，几年5岁，花色
		请编写一个程序，当用户输入小猫的名字时，就显示该猫的名字、
		年龄、颜色。当输入的名称错误时，则显示张老太没有这只猫猫
	*/
	var cats = make(map[string]Cat, 2)
	var cat1 Cat
	cat1.Name = "小白"
	cat1.Age = 3
	cat1.Color = "白色"
	cats[cat1.Name] = cat1
	var cat2 Cat
	cat2.Name = "小花"
	cat2.Age = 4
	cat2.Color = "花色"
	cats[cat2.Name] = cat2
	//fmt.Println(cats)
	var name string
	fmt.Println("请输入小猫的名字")
	fmt.Scanln(&name)
	cat, exist := cats[name]
	if exist {
		fmt.Println("猫猫的名字：", cat.Name)
		fmt.Println("猫猫的年龄：", cat.Age)
		fmt.Println("猫猫的颜色：", cat.Color)
	} else {
		fmt.Println("张老太没有这只猫猫")
	}
}

func structCopy() {
	var aa A
	aa.a = make(map[string]int)
	aa.a["asdf"] = 123
	bb := aa
	bb.a["asdf"] = 1231
	fmt.Println(aa)
	fmt.Println(bb)
}

func initStruct() {
	// 方式1 直接声明，见structDemo
	// 方式2
	var cat2 = Cat{"cat", 6, "blue"}
	cat2.Age = 5
	fmt.Println(cat2)
	// 方式3
	var cat3 *Cat = new(Cat)
	(*cat3).Name = "xiaomi"
	cat3.Name = "xiaomimi"
	// 也可以使用cat3.Name = "xiaomi"
	// 原因：go的设计者为了使用方便，底层会对cat3.Name = "xiaomi"进行处理，会在底层加上取值运算
	fmt.Println(*cat3)

	//方式4
	var cat4 *Cat = &Cat{Age: 6}
	// 因为cat4是一个指针，因此标准的访问字段的方法为
	(*cat4).Name = "xia4"
	cat4.Name = "xiao4"
	// cat4.Name = "xia4"也是可以的，原因见上
	fmt.Println(*cat4)
}
